﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ENG.TeachersDiary.Model;

namespace ENG.TeachersDiary.Classes
{
  class MarkGroupResult : Result
  {

    #region Properties

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
    private Model.MarkGroup _MarkGroup;
    ///<summary>
    /// Sets/gets MarkGroup value.
    ///</summary>
    public Model.MarkGroup MarkGroup
    {
      get
      {
        return (_MarkGroup);
      }
      set
      {
        _MarkGroup = value;
      }
    }

    public override string Title
    {
      get { return this.MarkGroup.Title; }
    }

    public override string Abbr
    {
      get { return this.MarkGroup.Abbr; }
    }

    private double _Sum = 0;
    public override double Sum
    {
      get { return _Sum; }
    }
    private double _Weight = 0;
    public override double Weight
    {
      get { return _Weight; }
    }

    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
    private List<String> _DisplayMarks = new List<string>();
    ///<summary>
    /// Sets/gets DisplayMarks value.
    ///</summary>
    public List<String> DisplayMarks
    {
      get
      {
        return (_DisplayMarks);
      }
      set
      {
        _DisplayMarks = value;
      }
    }

    public string DisplayMarksString
    {
      get
      {
        StringBuilder sb = new StringBuilder();
        bool isFirst = true;

        foreach (var fItem in DisplayMarks)
        {
          if (isFirst)
            isFirst = false;
          else
            sb.Append(", ");


          sb.Append(fItem);
        } // foreach (var fItem in DisplayMarks)

        if ((MarkGroup.IsLocallySummed) && (this.Weight != 0))
          sb.Append(" (=" + (this.Sum / this.Weight).ToString("0.00") + ")");


        return sb.ToString();
      }
    }

    #endregion Properties

    #region .ctor
    internal MarkGroupResult(MarkGroup markGroup)
    {
      this.MarkGroup = markGroup;
    }

    private MarkGroupResult() { }
    #endregion .ctor

    #region (Static) Create

    public static MarkGroupResult Create(Model.Student student, Model.MarkGroup markGroup)
    {
      MarkGroupResult ret = new MarkGroupResult();
      ret.DisplayMarks = new List<string>();
      var db = Common.DBConn;

      Program.UpdateProgress("Calculating result for student " + student.NameSurname + " - reading marks...");

      var mks = db.Marks.Where(i => (i.StudentID == student.StudentID) && (i.MarkGroupID == markGroup.MarkGroupID))
        .OrderBy(i => i.Date).OrderBy(i => i.MarkID);

      ret.MarkGroup = markGroup;

      Program.UpdateProgress("Calculating result for " + student.NameSurname + " - summing marks (" + mks.Count() + ")...");
      foreach (var fItem in mks)
      {
        ret.DisplayMarks.Add(fItem.MarkCode.Display);
        ret._Weight += markGroup.Weight;
        ret._Sum += fItem.MarkCode.Value * markGroup.Weight;
      } // foreach (var fItem in mks)

      Program.UpdateProgress("Calculating result for student " + student.NameSurname + " - finishing marks...");

      return ret;
    }
    #endregion (Static) Create

    internal void AddValue(Model.MarkGroup markGroup, Mark mark)
    {
      this.DisplayMarks.Add(mark.MarkCode.Display);
      this._Weight += markGroup.Weight;
      this._Sum += mark.MarkCode.Value * markGroup.Weight;
    }
  }
}
